package org.jeecg.modules.data.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.data.entity.DisExcelData;
import org.jeecg.modules.data.entity.TDataReport;
import org.jeecg.modules.data.entity.TDataStatistics;
import org.jeecg.modules.data.entity.TInvestigationRelease;
import org.jeecg.modules.data.mapper.TDataReportMapper;
import org.jeecg.modules.data.mapper.TDataStatisticsMapper;
import org.jeecg.modules.data.service.IDistrictService;
import org.jeecg.modules.data.service.ITDataStatisticsService;
import org.jeecg.modules.data.service.ITInvestigationReleaseService;
import org.jeecg.modules.data.util.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: t_data_statistics
 * @Author: jeecg-boot
 * @Date:   2025-05-20
 * @Version: V1.0
 */
@Service
public class TDataStatisticsServiceImpl extends ServiceImpl<TDataStatisticsMapper, TDataStatistics> implements ITDataStatisticsService {

    @Resource
    private TDataReportMapper reportMapper;
    @Resource
    private IDistrictService districtService;
    @Resource
    private ITInvestigationReleaseService inService;

    @Override
    public void saveOrUpStatis(TDataStatistics statistics) {
        TDataStatistics sParam = new TDataStatistics();
        sParam.setYear(statistics.getYear());
        sParam.setInvestigationId(statistics.getInvestigationId());
        // 查询地区编码是否存在统计数据，包括省市区
        String area = statistics.getCantCode(); // 区县
        String areaName = statistics.getCantName(); // 区县名称
        sParam.setCantCode(area);
        TDataStatistics areaS = selectDataByCantCode(sParam);
        if (areaS == null) { // 新增
            statistics.setId(UUIDGenerator.generateUUIDWithoutHyphens());
            statistics.setCantCode(area);
            statistics.setCantName(areaName);
            String name = "【"+areaName+"】"+statistics.getYear()+"年 " + statistics.getInvestigationName();
            statistics.setName(name);
            statistics.setType("3");
            statistics.setTownCount(1);
            statistics.setSamplingPointCount(1);
            this.save(statistics);
        } else { // 更新
            // 采集点
//            int spcount = areaS.getSamplingPointCount() + 1;
            TDataStatistics upParam = new TDataStatistics();
            upParam.setId(areaS.getId());
            upParam.setTownCount(reportMapper.getTownCount(area, statistics.getInvestigationId()));
            upParam.setSamplingPointCount(reportMapper.getPointCount(area, statistics.getInvestigationId()));
            BigDecimal averageLossRate = reportMapper.getAverageLossRate(area, statistics.getInvestigationId());
            upParam.setAverageLossRate(averageLossRate);
            this.updateById(upParam);
        }
        String city = statistics.getCity(); // 城市
        String cityName = statistics.getCityName(); // 城市名称
        sParam.setCantCode(city);
        TDataStatistics cityS = selectDataByCantCode(sParam);
        if (cityS == null) {
            statistics.setId(UUIDGenerator.generateUUIDWithoutHyphens());
            statistics.setCantCode(city);
            statistics.setCantName(cityName);
            String name = "【"+cityName+"】"+statistics.getYear()+"年 " + statistics.getInvestigationName();
            statistics.setName(name);
            statistics.setType("2");
            statistics.setTownCount(1);
            statistics.setSamplingPointCount(1);
            this.save(statistics);
        } else { // 更新
            // 采集点
//            int spcount = cityS.getSamplingPointCount() + 1;
            TDataStatistics upParam = new TDataStatistics();
            upParam.setId(cityS.getId());
            upParam.setTownCount(reportMapper.getTownCount(city, statistics.getInvestigationId()));
            upParam.setSamplingPointCount(reportMapper.getPointCount(city, statistics.getInvestigationId()));
            BigDecimal averageLossRate = reportMapper.getAverageLossRate(city, statistics.getInvestigationId());
            upParam.setAverageLossRate(averageLossRate);
            this.updateById(upParam);
        }
        String province = statistics.getProvince(); // 省份
        String provinceName = statistics.getProvinceName(); // 省份名称
        sParam.setCantCode(province);
        TDataStatistics provinceS = selectDataByCantCode(sParam);
        if (provinceS == null) {
            statistics.setId(UUIDGenerator.generateUUIDWithoutHyphens());
            statistics.setCantCode(province);
            statistics.setCantName(provinceName);
            String name = "【"+provinceName+"】"+statistics.getYear()+"年 " + statistics.getInvestigationName();
            statistics.setName(name);
            statistics.setType("1");
            statistics.setTownCount(1);
            statistics.setSamplingPointCount(1);
            this.save(statistics);
        } else { // 更新
            // 采集点
//            int spcount = provinceS.getSamplingPointCount() + 1;
            TDataStatistics upParam = new TDataStatistics();
            upParam.setId(provinceS.getId());
            upParam.setTownCount(reportMapper.getTownCount(province, statistics.getInvestigationId()));
            upParam.setSamplingPointCount(reportMapper.getPointCount(province, statistics.getInvestigationId()));
            BigDecimal averageLossRate = reportMapper.getAverageLossRate(province, statistics.getInvestigationId());
            upParam.setAverageLossRate(averageLossRate);
            this.updateById(upParam);
        }
    }

    @Override
    public TDataStatistics selectDataByCantCode(TDataStatistics statistics) {
        return this.baseMapper.selectDataByCantCode(statistics);
    }

    @Override
    public List<TDataStatistics> selectDataList(TDataStatistics tDataStatistics) {
        return this.baseMapper.selectDataList(tDataStatistics);
    }

    @Override
    public TDataStatistics getDataInfoById(String id) {
        return this.baseMapper.selectDataInfoById(id);
    }

    @Override
    public List<Map<String, String>> generateReportFiles(TDataStatistics statistics, String wordFile, String excelFile, String reporturl) {
        // 表格数据
        List<DisExcelData> excelList = new ArrayList<>();
        TDataStatistics province = null;
        // 1.查询所有县级统计列表生成word文档
        TDataStatistics query = new TDataStatistics();
        query.setInvestigationId(statistics.getInvestigationId());
        if (statistics.getType().equals("2")) { // 查询本市级
            query.setCity(statistics.getCantCode());
            DisExcelData data = new DisExcelData();
            BeanUtils.copyProperties(statistics, data);
            data.setCityno(1);
            excelList.add(data);
        } else if (statistics.getType().equals("1")){
            province = this.baseMapper.selectProvince(statistics.getInvestigationId());
            DisExcelData data = new DisExcelData();
            BeanUtils.copyProperties(province, data);
            excelList.add(data);
            findProvinceData(excelList, province);
        }
        query.setType("3");
        List<TDataStatistics> list = this.selectDataList(query);
        // 查询调查发布时间
        TInvestigationRelease release = inService.getById(statistics.getInvestigationId());
        List<Map<String, String>> result = new ArrayList<>();
        list.forEach(item -> {
            // 1.只查本市的县级数据，生成word文档
            TDataReport tDataReport = new TDataReport();
            tDataReport.setInvestigationId(item.getInvestigationId());
            tDataReport.setCantCode(item.getCantCode());
            List<TDataReport> report = reportMapper.selectAreaList(tDataReport);
            String cityName = districtService.getParentDistrict(item.getCantCode()).getShortName();
            String title = cityName + FileUtils.getTitile(item.getName());
            String fileName = title  + "机收损失监测调查汇总表" + FileUtils.generateRandomNumber() + ".docx";
            FileUtils.createWordFile(wordFile, reporturl, fileName, item, report);
            Map<String, String> map = new HashMap<>();
            map.put("fileName", fileName);
            map.put("filePath", reporturl + fileName);
            result.add(map);
            // 存储市级数据
            if (statistics.getType().equals("2")) {
                findData(excelList, item, report);
            }
        });
        // 2.生成汇总excel文档
        String fileName = null;
        if (statistics.getType().equals("1")) {
            fileName = "【汇总】" + statistics.getYear() + "年山东省机损监测统计【" + FileUtils.getType(statistics.getName()) + "】.xlsx";
        } else if (statistics.getType().equals("2")) {
            fileName = "【汇总】" + statistics.getYear() + "年"+statistics.getCantName()+"机损监测统计【" + FileUtils.getType(statistics.getName()) + "】.xlsx";
        }
        Map<String, String> map = new HashMap<>();
        map.put("fileName", fileName);
        map.put("filePath", reporturl + fileName);
        result.add(map);
        String reportDate = DateUtils.formatDate(release.getStartTime());
        FileUtils.createExcelFile(excelFile, reporturl, fileName, statistics, excelList, reportDate);
        return result;
    }

    @Override
    public void updateBatchByReport(TDataReport tDataReport) {
        TInvestigationRelease ti = inService.getById(tDataReport.getInvestigationId());
        // 获取年份
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(ti.getStartTime());
        int year = calendar.get(Calendar.YEAR);
        // 查统计数据
        String cantCode = tDataReport.getCantCode();
        String[] codes = cantCode.split(":");
        // 省级
        TDataStatistics provSq = new TDataStatistics();
        provSq.setCantCode(codes[0]);
        provSq.setYear(year);
        provSq.setInvestigationId(tDataReport.getInvestigationId());
        TDataStatistics provS = selectDataByCantCode(provSq);
        // 市级
        TDataStatistics citySq = new TDataStatistics();
        citySq.setCantCode(codes[1]);
        citySq.setYear(year);
        citySq.setInvestigationId(tDataReport.getInvestigationId());
        TDataStatistics cityS = selectDataByCantCode(citySq);
        // 区县
        TDataStatistics areaSq = new TDataStatistics();
        areaSq.setCantCode(codes[2]);
        areaSq.setYear(year);
        areaSq.setInvestigationId(tDataReport.getInvestigationId());
        TDataStatistics areaS = selectDataByCantCode(areaSq);

        // 省级采样点为0时，删除省市区统计数据
        int provcount = provS.getSamplingPointCount() - 1;
        int citycount = cityS.getSamplingPointCount() - 1;
        int areacount = areaS.getSamplingPointCount() - 1;
        if (provcount == 0) {
            this.removeById(provS.getId());
            this.removeById(cityS.getId());
            this.removeById(areaS.getId());
        } else {
            provS.setSamplingPointCount(provcount);
            cityS.setSamplingPointCount(citycount);
            areaS.setSamplingPointCount(areacount);
            // 更新省统计
            provS.setTownCount(reportMapper.getTownCount(codes[0], tDataReport.getInvestigationId()));
            BigDecimal pRate = reportMapper.getAverageLossRate(codes[0], tDataReport.getInvestigationId());
            provS.setAverageLossRate(pRate);
            this.updateById(provS);
            // 更新市统计
            cityS.setTownCount(reportMapper.getTownCount(codes[1], tDataReport.getInvestigationId()));
            BigDecimal cRate = reportMapper.getAverageLossRate(codes[1], tDataReport.getInvestigationId());
            cityS.setAverageLossRate(cRate);
            this.updateById(cityS);
            // 更新区县统计
            areaS.setTownCount(reportMapper.getTownCount(codes[2], tDataReport.getInvestigationId()));
            BigDecimal aRate = reportMapper.getAverageLossRate(codes[2], tDataReport.getInvestigationId());
            areaS.setAverageLossRate(aRate);
            this.updateById(areaS);
        }
    }

    private List<DisExcelData> findData(List<DisExcelData> excelList, TDataStatistics area, List<TDataReport> details) {
        if (area != null) {
            for (int i = 0; i < details.size(); i++) {
                DisExcelData detail = new DisExcelData();
                BeanUtils.copyProperties(area, detail);
                BeanUtils.copyProperties(details.get(i), detail);
                detail.setCityno(1);
                detail.setAreano(i+1);
                excelList.add(detail);
            }
        }
        return excelList;
    }

    private List<DisExcelData> findProvinceData(List<DisExcelData> excelList, TDataStatistics province) {
        // 查所有市级
        TDataStatistics query = new TDataStatistics();
        query.setInvestigationId(province.getInvestigationId());
        query.setType("2");
        List<TDataStatistics> cityList = this.selectDataList(query);
        for (int i = 0; i < cityList.size(); i++) {
            // 市
            TDataStatistics city = cityList.get(i);
            DisExcelData cityData = new DisExcelData();
            BeanUtils.copyProperties(city, cityData);
            cityData.setCityno(i + 1);
            excelList.add(cityData);
            // 县统计
            TDataStatistics areaQ = new TDataStatistics();
            areaQ.setInvestigationId(city.getInvestigationId());
            areaQ.setCity(city.getCantCode());
            areaQ.setType("3");
            List<TDataStatistics> areaList = this.selectDataList(areaQ);
            int finalI = i;
            areaList.forEach(area -> {
                List<DisExcelData> dataList = this.baseMapper.selectDisExcelDataList(area);
                dataList.forEach(item -> {
                    item.setCityno(finalI + 1);
                });
                excelList.addAll(dataList);
            });
        }
        return excelList;
    }
}
